// 编程范式：命令式编程/声明式编程
// 编程范式：面向对象编程（第一公民：对象）/函数式编程（第一公民：函数）
// 高阶函数：filter/map/reduce
/*
*   filter中的回调函数有一个要求：必须返回一个Boolean值
*   true：当返回true时，函数内部会自动将这次回调的n加入到新的数组中，这个新的数组是函数内部自动生成的，我们let一个数组来接收它就可以了
*   false：当返回false时，函数内部会过滤掉这次的n
* */
const nums=[10,20,30,111,333,444,40,50];
//1.需求：取出所有小于100的数字
//普通方法
/*let newNum=[];
for(let num of nums){
  if(num<100){
    newNum.push(num);
  }
}*/
//filter函数的使用： filter(回调函数)
let newNum=nums.filter(function (n){ /* 每回调一次函数，里面的n就是数组的一个元素，所以一共回调7次*/
  return n<100
})
console.log(newNum); // [10,20,30,40,50]




/*
*  map()函数不会改变原数组的内容，会将修改后的数组存储到新的数组中，再返回
* */
//2.需求：将所有小于100的数字进行转化：全部*2
//普通方法
/*let new2Num=[];
for(let n of newNum){
  new2Num.push(n*2);
}
console.log(new2Num);*/
//map函数的使用：map(回调函数)
let new2Num=newNum.map(function (n){
  return n*2;
})
console.log(new2Num); // [20,40,60,80,100]

let new3Num=newNum.map(function(n){
  return 100;
})
console.log(new3Num); //[100,100,100,100,100]



/*
* reduce函数的作用：对数组中的所有内容进行汇总
* new2Num.reduce(回调函数),回调函数中至少要传两个值
*  第一个：上一次回调函数里面返回的值
*  第二个：当前正在遍历的n
* */
//3.需求：将所有new2Num的数字相加，得到最终的结果
//普通方法
/*
let sum=0;
for(let i of new2Num){
  sum+=i;
}
console.log(sum);*/
//reduce函数的使用：
let sum=new2Num.reduce(function (preValue,n){
  return preValue+n;
},0)
// 第一次  preValue 0   n 20
// 第二次  preValue 20   n 40
// 第三次  preValue 60   n 60
// 第四次  preValue 120   n 80
// 第五次  preValue 200   n 100
// return 300；
console.log(sum); // 300


// filter,map,reduce合并使用
let sum1=nums.filter(function (n){
  return n<100;
}).map(function (n){
  return n*2;
}).reduce(function(preValue,n){
  return preValue+n;
},0)
console.log(sum1); //300

// 箭头函数的简写
let total=nums.filter(n=>n<100).map(n=>n*2).reduce((pre,n)=>pre+n);
console.log(total);